package kuzmenkov.oip.adapters.uiip.imagework;

import kuzmenkov.oip.adapters.ImageProcessingAdapter;
import kuzmenkov.oip.common.FileTool;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import swt.image.tools.SWT2DAlgth;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.renderable.ParameterBlock;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * This class adapts an object detection module to use one by a web-interface. 
 * User: Michael Kuzmenkov
 * Date: 23.04.2009
 * Time: 22:48:41
 */
public class ObjectDetectionAdapter extends ImageProcessingAdapter{
    private Logger log = Logger.getLogger(ObjectDetectionAdapter.class.getName());

    /**
     * Detects an object on an image. It take a few patameters:
     *      a relative path to a source image (image)
     *      a ROI with the object (selection)
     *      ...
     * It returns three results:
     *      a path to the source image (image)
     *      a list of graphic paths that represents detected objects (polygons)
     *      a path to an object image (image)
     *
     * @param params
     * @return
     * @throws Exception
     */
    public Object[] process(Object[] params) throws Exception {
        String sourcePath = (String) params[0];
        Rectangle2D objectSelection = (Rectangle2D) params[1];

        String destinationPath = sourcePath;

        FileTool ftool = FileTool.getInstance();
        sourcePath = ftool.relPathToAbs(sourcePath);

        String dstFileName = "object.png";
        String objectPath = ftool.getTempDir(getSessionId())+dstFileName;
        cropAndStoreImage(sourcePath,objectPath,objectSelection);

        Display device = new Display();
        Image srcImage = new Image(device,sourcePath);
        Image objImage = new Image(device,objectPath);

        //TODO
        List<Point[]> recognObjects = SWT2DAlgth.ObjectDetectAlg(objImage,srcImage,null);

        List<Path2D> polygons = convertTo(recognObjects);

        String objRelPath = ftool.getRelativeTempDir(getSessionId())+dstFileName;
        return new Object[]{destinationPath,polygons,objRelPath};  
    }

    private List<Path2D> convertTo (List<Point[]> slist) {
        List<Path2D> dlist = new ArrayList<Path2D>(slist.size());
        for (Point[] polygon : slist){
            Path2D path = new Path2D.Float();
            Point initialPoint = polygon[0];
            path.moveTo(initialPoint.x,initialPoint.y);
            for (int i=1; i<polygon.length;i++){
                Point p = polygon[i];
                path.lineTo(p.x,p.y);  
            }
            dlist.add(path);
        }
        return dlist;
    }

    /**
     * Crops and store an image
     * @param srcPath the source image
     * @param dstPath the destination image
     * @param roi the region of the interest
     */
    private void cropAndStoreImage (String srcPath, String dstPath, Rectangle2D roi) {

        RenderedOp srcImage = JAI.create("fileload", srcPath);

        Float x = (float) roi.getX();
        Float y = (float) roi.getY();
        Float width = (float) roi.getWidth();
        Float height = (float) roi.getHeight();

        ParameterBlock block = new ParameterBlock();
        block.addSource(srcImage);
        block.add(x);
        block.add(y);
        block.add(width);
        block.add(height);
        RenderedOp cropImage = JAI.create("crop", block, null);

        // Translate the image origin.
        block = new ParameterBlock();
        block.addSource(cropImage);
        block.add(-x);
        block.add(-y);

        // Create the output image by translating itself.
        RenderedOp dstImage = JAI.create("translate", block, null);

        JAI.create("filestore", dstImage, dstPath, "PNG", null);
    }
}
